﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace EAPtoHTML
{
    static class EAExtensions
    {
        public static void toHTML(this EA.Repository r, string ExportTo, int LimitRecordsTo){

            List<DiagramData> //used to hold all of the data we want to export
                DiagramDataList = new List<DiagramData>();
            bool Limit = false;
            if (LimitRecordsTo > 0) Limit = true;

            //action to save the data in some viewable format
            Action SaveData = () =>
            {

                // Copy the static site template folder
                string source = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName + "\\ExportTemplate";
                string target = ExportTo;
                source.CopyThisFolderTo(target);

                // save the data to json
                DiagramDataList.SaveMetaDataAsJSON(ExportTo + "\\data\\json_data.txt");

                // save the diagram images
                DiagramDataList.SaveDiagramsAsPNG(ref r, ExportTo);

            };

            // action to get the data from EA that we want to see
            Action GetData = () =>
            {

                // action to process the package collections
                Action<IEnumerable<EA.Package>> ppc = null;
                ppc = (EAPackages) =>
                {
                    foreach (EA.Package p in EAPackages)
                    {//for every child package
                        foreach (EA.Diagram d in p.Diagrams)
                        {//process all the diagrams
                            if (Limit && DiagramDataList.Count == LimitRecordsTo) return; //some simple record limiting for testing
                            DiagramDataList.Add(new DiagramData(r, p, d));//add diagram data to our results
                        }
                        //process any children
                        ppc(p.Packages.Cast<EA.Package>());
                    }
                };

                //process the package collections recursively, start with the base package collection
                ppc(r.Models.Cast<EA.Package>());

            };

            //some timing for testing
            DateTime timer = DateTime.Now;

            //get data
            Console.Write("getting data from EAP... ");
            GetData();
                        Console.WriteLine("done! ({0} elapsed)", (DateTime.Now - timer).ToString());
            timer = DateTime.Now;
            Console.WriteLine("\tdata retrieved for {0} diagrams", DiagramDataList.Count().ToString());

            //save data
            Console.Write("saving data to {0}... ",ExportTo);
            SaveData();
            Console.WriteLine("done! ({0} elapsed)", (DateTime.Now - timer).ToString());
            timer = DateTime.Now;
            
        }
        public static void toHTML(this EA.Repository r, string ExportTo){
            r.toHTML(ExportTo, 0);
        }
        //this function is for getting all of the 'raw' text that we want
        //  out of a diagram. i am just getting the name and notes
        public static string GetNamesAndNotes(this EA.Diagram d, EA.Repository r)
        {

            //sb to hold the keywords
            StringBuilder sb = new StringBuilder();

            // add the diagram GUID, NAME, and NOTES
            sb.Append(string.Join(" ", new string[] { d.DiagramGUID, d.Name, d.Notes }));

            // action to iterate elements and get their name and notes, uses stringbuilder above
            Action<EA.Element> EnumerateElements = null;
            EnumerateElements = (e) =>
            {
                if (!e.Notes.Length.Equals(0))
                    sb.AppendLine(string.Join(" ", new string[] { e.Name, e.Notes }));
                foreach (EA.Element ee in e.Elements)
                    EnumerateElements(ee);
            };

            // invoke the func to iterate the elements
            foreach (EA.DiagramObject o in d.DiagramObjects)
                EnumerateElements(r.GetElementByID(o.ElementID));

            //return all of the text we want
            return sb.ToString();

        }

    }
}
